package fr.cephb.net;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;

import fr.cephb.io.IOUtils;
import fr.cephb.util.JSONBuilder;
import fr.cephb.util.JSONizable;

/**
 * HttpApplication
 *
 */
public abstract class HttpApplication
implements HttpHandler
{
private static final Logger LOG=Logger.getLogger("fr.cephb.joperon");
public static int DEFAULT_PORT=8070;
protected int port=DEFAULT_PORT;

public abstract void handle(HttpExchange exchange) throws IOException;

public static int getDefaultPort() {
	return DEFAULT_PORT;
	}


public static void setDefaultPort(int defaultPort) {
	DEFAULT_PORT = defaultPort;
	}

/**
 * Http Parameter
 * @author lindenb
 *
 */
protected static class Parameter
	implements JSONizable
	{
	private String name;
	private String value;
	Parameter(String name,String value)
		{
		this.name=name;
		this.value=value;
		}
	
	@Override
	public String toJSON() {
		JSONBuilder b= new JSONBuilder();
		b.put("key",getName()).put("value", getValue());
		return b.getString();
		}
	
	public String getName() {
		return name;
	}
	
	public String getValue() {
		return value;
	}
	
	@Override
	public String toString() {
		return toJSON();
		}
	
	}

public int getPort() {
	return port;
}

protected Properties getDefaultParamProperties()
	{
	return new Properties();
	}

public Properties getParametersAsMap(HttpExchange http) throws IOException
	{
	Properties prop= new Properties(getDefaultParamProperties());
	for(Parameter param:getParameters(http))
		{
		prop.setProperty(param.getName(), param.getValue());
		}
	return prop;
	}

public List<Parameter> getParameters(HttpExchange http) throws IOException
	{
	LOG.info("Reading parameters");
	List<Parameter> params= new ArrayList<Parameter>();
	String query=null;
	if(http.getRequestMethod().equalsIgnoreCase("GET"))
		{
		query= http.getRequestURI().getRawQuery();
		}
	else if(http.getRequestMethod().equalsIgnoreCase("POST"))
		{
		InputStream in=http.getRequestBody();
		if(in==null) throw new IOException("Cannot get POST query request is null");
		try {
			ByteArrayOutputStream baos= new ByteArrayOutputStream();
			IOUtils.copyTo(in, baos);
			baos.close();
			query= new String(baos.toByteArray());
			} 
		catch (IOException e)
			{
			throw e;
			}
		catch (Throwable e)
			{
			throw new IOException(e);
			} 
		finally
			{
			in.close();
			}
		}
	else
		{
		throw new IOException("Unsupported Method:"+http.getRequestMethod());
		}
	
	if(query!=null)
		{
		for(String s:query.split("[&]"))
	        {
	        s=s.replace('+', ' ');
	        int eq= s.indexOf('=');
	        if(eq>0)
	            {
	        	Parameter param=new Parameter(
		            	URLDecoder.decode(s.substring(0,eq),"UTF-8"),
		                URLDecoder.decode(s.substring(eq+1),"UTF-8")
		                );
	            params.add(param);
	            LOG.info("found param "+param);
	            }
	        }
		}
	
	return params;
	}



}
